#pragma once
#include "Common.hpp"
#include "ObjectPool.hpp"
#include "ThreadCache.h"
#include "PageCache.h"

void *ConcurrentAlloc(size_t size)
{
    if (size <= MAX_BYTES)
    {
        if (gc_TLS._threadCache == nullptr)
        {
            static ObjectPool<ThreadCache> tcPool; // 所有线程共享的静态tcPoll
            gc_TLS.GetThreadCache(&tcPool);
        }
        // cout << std::this_thread::get_id() << ": " << gc_TLS._threadCache << endl; //debug
        return gc_TLS._threadCache->Allocate(size);
    }
    else
    {
        // 内存块大小超过MAX_BYTES就直接向PageCache申请
        size_t alineSize = AlineRule::RoundUp(size);
        size_t k = alineSize >> PAGE_SHIFT;
        // cout << std::this_thread::get_id() << ": Alloc " << k << " pages!"<< endl; //debug
        Span *kspan = PageCache::GetInstance()->NewSpan(k);
        kspan->_objSize = size;
        return (void *)(kspan->_pageId << PAGE_SHIFT);
    }
}

void ConcurrentFree(void *ptr)
{
    Span *span = PageCache::GetInstance()->MapObjectToSpan(ptr);
    size_t objSize = span->_objSize;
    if (objSize <= MAX_BYTES)
    {
        assert(gc_TLS._threadCache != nullptr);
        gc_TLS._threadCache->Deallocate(ptr, objSize);
    }
    else
    {
        // cout << std::this_thread::get_id() << ": Dealloc " << span->_pageNum << " pages!"<< endl; //debug
        PageCache::GetInstance()->ReleaseSpanToPageCache(span);
    }
}